package main

import "fmt"

/*
二叉搜索树的最近公共祖先（搜索树）
给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为：“对于有根树 T 的两个结点 p、q，最近公共祖先表示为一个结点 x，
满足 x 是 p、q 的祖先且 x 的深度尽可能大（一个节点也可以是它自己的祖先）。”

示例 1:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
输出: 6
解释: 节点 2 和节点 8 的最近公共祖先是 6。

示例 2:
输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
输出: 2
解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。
*/

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}

//递归
func lowestCommonAncestor1(root, p, q *TreeNode) (ancestor *TreeNode) {
	ancestor = root
	for {
		//如果当前节点的值大于p和q的值，说明p和q应该在当前节点的左子树，因此将当前节点移动到它的左子节点；
		if p.Val < ancestor.Val && q.Val < ancestor.Val {
			ancestor = ancestor.Left
			//如果当前节点的值小于p和q的值，说明p和q应该在当前节点的右子树，因此将当前节点移动到它的右子节点；
		} else if p.Val > ancestor.Val && q.Val > ancestor.Val {
			ancestor = ancestor.Right
		} else { //如果当前节点的值不满足上述两条要求，那么说明当前节点就是「分岔点」。
			//此时p和q要么在当前节点的不同的子树中，要么其中一个就是当前节点。
			return
		}
	}
}

func lowestCommonAncestor2(root *TreeNode, p int, q int) int {
	// write code here
	tmp := root
	for {
		if p < tmp.Val && q < tmp.Val {
			tmp = tmp.Left
		} else if p > tmp.Val && q > tmp.Val {
			tmp = tmp.Right
		} else {
			return tmp.Val
		}
	}
}

func main() {
	A := &TreeNode{Val: 6}
	A.Left = &TreeNode{Val: 2}
	A.Right = &TreeNode{Val: 8}
	A.Left.Left = &TreeNode{Val: 0}
	A.Left.Right = &TreeNode{Val: 4}
	A.Right.Left = &TreeNode{Val: 7}
	A.Right.Right = &TreeNode{Val: 9}
	A.Left.Right.Left = &TreeNode{Val: 3}
	A.Left.Right.Left = &TreeNode{Val: 5}
	fmt.Println(lowestCommonAncestor1(A, A.Left.Right.Left, A.Right))
}
